package item05;

import org.junit.Assert;
import org.junit.Test;

/**
 * @author Lv Jing
 * @date 2018年07月11日 0:40
 */
public class ReplaceBlank {

    /*
    替换空格：替换字符串中的空格为%20，即一个字符变三个字符
    思路：比较粗暴的方法是从头到尾遍历，遇到空格就把后面的字符串往后移动两位，然后就有三个空出来的字符位置，可以容纳%20。
    但是这样会造成字符串移动的次数过多，可以优化成从尾到头遍历，这里先计算出字符串在替换空格后的长度，然后一个游标放在替换字符
    串后的末尾，一个游标放在原始字符串的末尾，每向前移动一个字符就把它复制到新的字符串中，如果遇到空格，就把新字符串的游标向前
    移动三位然后复制%20。
     */

    private String replace(String str) {
        // 非法输入校验
        if (str == null || str.equals("")) {
            return str;
        }

        char[] charArr = str.toCharArray();
        int blankCount = 0;
        for (char value : charArr) {
            if (value == ' ') {
                blankCount++;
            }
        }

        // 没有空格，后面流程不需要
        if (blankCount == 0) {
            return str;
        }

        char[] newStr = new char[str.length() + blankCount*2];
        int oldIndex = charArr.length - 1;
        int newIndex = newStr.length - 1;
        // 这里需要注意下，书上写的第二个判断条件是大于，但是当判断空格后没有其他空格了时，是会出错的。如  "ab "
        while (oldIndex >= 0 && newIndex >= oldIndex) {
            char oldValue = charArr[oldIndex];
            // 非空格，直接复制
            if (oldValue != ' ') {
                newStr[newIndex--] = oldValue;
            } else {
                newStr[newIndex--] = '0';
                newStr[newIndex--] = '2';
                newStr[newIndex--] = '%';
            }
            oldIndex--;
        }
        return new String(newStr);
    }

    /**
     * 非法输入，空字符串或空对象
     */
    @Test
    public void test01() {
        Assert.assertNull(replace(null), null);
        Assert.assertEquals(replace(""), "");
    }

    /**
     * 没有空格的字符串
     */
    @Test
    public void test02() {
        Assert.assertEquals(replace("ab"), "ab");
    }

    /**
     * 有空格
     */
    @Test
    public void test03() {
        Assert.assertEquals(replace(" ab"), "%20ab");
        Assert.assertEquals(replace("ab "), "ab%20");
        Assert.assertEquals(replace("a b"), "a%20b");
        Assert.assertEquals(replace("a  b"), "a%20%20b");
    }
}
